home *** CD-ROM | disk | FTP | other *** search
/ Hackers Handbook - Millenium Edition / Hackers Handbook.iso / library / hack99 / ncftpd_2.txt < prev    next >
Encoding:
Internet Message Format  |  1999-03-26  |  4.1 KB

  1. Date: Tue, 23 Feb 1999 14:59:14 -0400
  2. From: Julien Nadeau <sw3wn@csoft.net>
  3. To: PacketStorm@genocide2600.com
  4. Subject: NcFTPd remote buffer overflow
  5.  
  6. Proof of Concept - Security Advisory                        02/23/99
  7. http://poc.csoft.net                                     Released by
  8. poc@csoft.net                                    sw3wn@poc.csoft.net
  9.  
  10. ---
  11.  
  12. Affected Program        NcFTPd <http://www.ncftp.com>
  13. Description             FTP server (commercial)
  14. Severity                Theoretical root compromise, logs compromise
  15.  
  16.  
  17. Synopsis:
  18.  
  19. NcFTPd is a commercial FTP (File Transfer Protocol) server, in the
  20. NcFTP product line.  The source code is not publicly released.  This
  21. was tested on Linux with libc5 (there's a glibc2 specific version
  22. available).
  23.  
  24. Problem:
  25.  
  26. NcFTPd's PORT parsing function has a stack buffer overflow
  27. problem, which would basically allow a user to remotely execute
  28. arbitrary code - the thing here is that the PORT parsing function
  29. seem to change characters, that are not in the range 0x30-0x39
  30. (ASCII '0'-'9'), into 0x20 (ASCII space), hence making an exploit
  31. almost impossible (note that, if ascii 0x40 would be allowed that
  32. would be a different story =p).
  33.  
  34. The program only parses for characters out of the 0-9 range in a
  35. specific area in memory (the one that contains return address heh)
  36. - the rest is kept unchanged, and you can't really go further in
  37. memory, input line size is restricted.
  38.  
  39. Like with most buffer overflows there are probably work-arounds to
  40. exploit it - this could have been a particulary neat exploit, since
  41. it runs as a child and one could gain access transparently without
  42. crashing the parent.
  43.  
  44. The current bug is not really a problem, it can crash the child process
  45. with a segfault, the parent process receives a signal 6 (abort) and the
  46. child process stay zombie for a few seconds and a brand new one is
  47. created.
  48. A few minor DoS attacks are possible but, who cares.  Oh and this could
  49. be
  50. used to not get listed in the logs too.
  51.  
  52. Example:
  53.  
  54. --
  55. evil:$ nc victim ftp
  56. 220 victim NcFTPd Server (unregistered copy) ready.
  57. user anonymous
  58. 331 Guest login ok, send your complete e-mail address as password.
  59. pass some@thing
  60. 230-You are user #1 of 50 simultaneous users allowed.
  61. 230-
  62. 230 Logged in anonymously.
  63. port 00000000000000000000000000000000000000000000 (...)
  64. 501 Syntax error in parameters.
  65. evil:$
  66. --
  67.  
  68.  
  69. Status:
  70.  
  71. I contacted the authors, nice enough to send me back the piece
  72. of code that causes the problem - here goes:
  73.  
  74. static int
  75. ftp_aton(const char *cp, struct sockaddr_in *sinaddr)
  76. {
  77.         char buf[64];
  78.         char *dst;
  79.         char *dstlim;
  80.         int i, c;
  81.         unsigned int octets[6], u;
  82.  
  83.         memset(sinaddr, 0, sizeof(struct sockaddr_in));
  84.         dst = buf;
  85.         dstlim = dst + sizeof(buf);
  86.  
  87.         for ( ; ; ) {
  88.                 c = *cp++;
  89.                 if (c == '\0')
  90.                         break;
  91.                 if (! isdigit(c))
  92.                         c = ' ';
  93.                 if (dst < dstlim)
  94.                         *dst++ = c;
  95.         }
  96.         *dst = '\0';
  97.  
  98.         if (sscanf(buf, "%u%u%u%u%u%u",
  99.                 &octets[0],
  100.                 &octets[1],
  101.                 &octets[2],
  102.                 &octets[3],
  103.                 &octets[4],
  104.                 &octets[5]
  105.         ) != 6) {
  106.                 return (-1);
  107.         }
  108.  
  109.         for (i=0; i<6; i++) {
  110.                 if (octets[i] > 0xFF)
  111.                         return (-1);
  112.         }
  113.  
  114.         sinaddr->sin_family = AF_INET;
  115.         u = (octets[0] << 24)
  116.                 | (octets[1] << 16)
  117.                 | (octets[2] << 8)
  118.                 | (octets[3]);
  119.         sinaddr->sin_addr.s_addr = htonl(u);
  120.         u = (octets[4] << 8) | (octets[5]);
  121.         sinaddr->sin_port = htons((unsigned short) u);
  122.         return (0);
  123. }       /* ftp_aton */
  124.  
  125.  
  126. void
  127. Port(char *line)
  128. {
  129.          if (gLoggedIn == 0) {
  130.                 NotLoggedIn();
  131.                 return;
  132.         }
  133.         if (gAllowPORT == 0) {
  134.                 Reply("550 This site does not permit PORT.  Please use
  135. PASV
  136. instead.\r\n");
  137.                 return;
  138.         }
  139.  
  140.         if (ftp_aton(line, &gRemoteDataAddr) < 0) {
  141.                 Reply("501 Syntax error in parameters.\r\n");
  142.                 return;
  143.         }
  144.         /* ... */
  145. }
  146.  
  147.